﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using System.Xml;
using System.Configuration;
using System.Threading;
using System.Text.RegularExpressions;

using XPTable.Editors;
using XPTable.Models;

using OneMake.DataAccess;
using OneMake.Model;
using OneMake.Excel;

namespace OneMake.Winforms
{
    public partial class DataManageForm : Form
    {
        private string MySelectedPath = "";
        private DataHelper dataHelper = new DataHelper();
        private List<keyword2model> keyword2Models = new List<keyword2model>();
        private Thread thread = null;
        private int currentShopId = 0;

        public DataManageForm()
        {
            InitializeComponent();
            
        }

        //初始化配置
        private void initKeyWordMap()
        {
            keyword2Models.Clear();

            XmlDocument doc = new XmlDocument();
            doc.Load(@"keyword2model.config");  // TODO:配置文件的路径
            XmlNodeList nodes = doc.SelectSingleNode(@"configuration//keyword2model").ChildNodes;
            foreach (XmlElement node in nodes)
            {
                keyword2model km = new keyword2model();
                km.Keyword = node.Attributes["keyword"].Value;
                km.Type = node.Attributes["type"].Value;
                km.TimeType = node.Attributes["time"].Value;
                km.Value = node.Attributes["value"].Value;
                keyword2Models.Add(km);
            }
        }
        //获取所有的表格类型
        private string[] getFileTypes()
        {
            List<string> fileTypes = new List<string>();
            foreach (keyword2model km in keyword2Models)
                fileTypes.Add(km.Type);
            return fileTypes.ToArray();
        }
        
        //载入所有的店铺
        private void LoadShops()
        {
            cbShops.DataSource = dataHelper.GetShops();
            cbShops.DisplayMember = "name";
            cbShops.ValueMember = "shopid";

            cbShopList.DataSource = dataHelper.GetShops();
            cbShopList.DisplayMember = "name";
            cbShopList.ValueMember = "shopid";
        }
        //初始化XPTable控件
        private void InitFileTable()
        {
            this.fileTable.BeginUpdate();

            TextColumn fileName = new TextColumn();
            fileName.Text = "文件名";
            fileName.ToolTipText = "待导入的文件名";
            fileName.Width = 350;

            ComboBoxColumn fileType = new ComboBoxColumn();
            fileType.Text = "文件类型";
            fileType.ToolTipText = "待导入的文件类型";
            fileType.Width = 200;

            ComboBoxCellEditor fileTypeEditor = new ComboBoxCellEditor();
            fileTypeEditor.DropDownStyle = DropDownStyle.DropDownList;
            fileTypeEditor.Items.AddRange(getFileTypes());
            fileType.Editor = fileTypeEditor;

            ComboBoxColumn dateType = new ComboBoxColumn();
            dateType.Text = "时间类型";
            dateType.ToolTipText = "待导入的文件时间类型";
            dateType.Width = 100;

            ComboBoxCellEditor dateTypeEditor = new ComboBoxCellEditor();
            dateTypeEditor.DropDownStyle = DropDownStyle.DropDownList;
            dateTypeEditor.Items.AddRange(new string[] { "天", "周", "月"});
            dateType.Editor = dateTypeEditor;

            DateTimeColumn startDate = new DateTimeColumn();
            startDate.CustomDateTimeFormat = "yyyy-MM-dd";
            startDate.DateTimeFormat = System.Windows.Forms.DateTimePickerFormat.Short;
            startDate.Format = "yyyy-MM-dd";
            startDate.Text = "所属日期范围";
            startDate.ToolTipText = "该数据所属的日期";
            startDate.Visible = true;
            startDate.Width = 120;

            DateTimeColumn endDate = new DateTimeColumn();
            endDate.CustomDateTimeFormat = "yyyy-MM-dd";
            endDate.DateTimeFormat = System.Windows.Forms.DateTimePickerFormat.Short;
            endDate.Format = "yyyy-MM-dd";
            endDate.Text = "所属日期范围";
            endDate.ToolTipText = "该数据所属的日期";
            endDate.Visible = true;
            endDate.Width = 120;

            CheckBoxColumn fileCheck = new CheckBoxColumn();
            fileCheck.Alignment = XPTable.Models.ColumnAlignment.Center;
            fileCheck.DrawText = false;
            fileCheck.Text = "是否导入";
            fileCheck.ToolTipText = "文件是否选定";
            fileCheck.Width = 70;

            TextColumn errorInfo = new TextColumn();
            errorInfo.Text = "导入结果";
            errorInfo.ToolTipText = "导入错误提示";
            errorInfo.Width = 300;

            this.fileTable.ColumnModel = new ColumnModel(new Column[] {fileName,
																	  fileType,
                                                                      dateType,
																	  startDate,
                                                                      endDate,
																	  fileCheck,
                                                                      errorInfo});

            DateTime dt = DateTime.Now;
            this.fileTable.TableModel = new TableModel();

            this.fileTable.HeaderRenderer = new XPTable.Renderers.GradientHeaderRenderer();
            this.fileTable.TableModel.RowHeight += 3;
            this.fileTable.FullRowSelect = true;

            this.fileTable.EndUpdate();
        }
        
        //获取所有的xls、cvs文件
        private void GetAllDirList(string strBaseDir, ArrayList al)
        {
            DirectoryInfo di = new DirectoryInfo(strBaseDir);//获得目录信息
            string[] filters = new string[] { ".csv", ".xls", ".xlsx" };

            //获得该目录下的指定类型的文件;
            FileInfo[] fiA = di.GetFiles("*.*");
            for (int j = 0; j < fiA.Length; j++)
            {
                foreach (string fi in filters)
                {
                    if (fiA[j].Extension.ToLower() == fi)
                    {
                        //过滤掉打开的office临时文件;
                        if (!fiA[j].Name.StartsWith(@"~$"))
                        {
                            al.Add(fiA[j]);
                        }
                        break;
                    }
                }
            }


            //子目录递归
            DirectoryInfo[] diA = di.GetDirectories();//获得该目录下的所有子目录
            for (int i = 0; i < diA.Length; i++)
            {
                GetAllDirList(diA[i].FullName, al);
            }
        }
        //从文件信息获取导入信息
        public ImportInfo getImportFileInfo(FileInfo fileInfo)
        {
            ImportInfo ii = new ImportInfo();
            ii.IsImport = false;
            ii.FullName = fileInfo.FullName;
            foreach (keyword2model km in keyword2Models)
            {
                if (fileInfo.FullName.Contains(km.Keyword))
                {
                    ii.FileType = km.Type;
                    ii.TimeType = km.TimeType;
                    ii.IsImport = true;
                    break;
                }
            }

            //尝试获取日期(初始为当前时间)
            ii.BeginTime = DateTime.Now;
            ii.EndTime = DateTime.Now;
            bool bFound = false;

            //这一行很关键;
            string filename = Path.GetFileName(ii.FullName);

            try
            {
                //查找YYYY-MM-DD格式的日期;
                Regex reg = new Regex(@"\d{4}[-/.]\d{1,2}[-/.]\d{1,2}");
                MatchCollection mc = reg.Matches(filename);
                for (int i = 0; i < mc.Count; i++)
                {
                    if (i == 0)
                    {
                        ii.BeginTime = DateTime.Parse(mc[i].Groups[0].Value);
                        ii.EndTime = DateTime.Parse(mc[i].Groups[0].Value);
                    }
                    if (i == 1)
                    {
                        ii.EndTime = DateTime.Parse(mc[i].Groups[0].Value);
                    }
                    bFound = true;
                }
            }
            catch (System.Exception ex)
            {
                //出现过2011-06-31这样不存在的日期的情况!
                ii.IsImport = false;
            }

            if (!bFound)
            {
                //查找YYYY-MM的月份;
                Regex reg2 = new Regex(@"\d{4}[-/.]\d{1,2}");
                MatchCollection mc2 = reg2.Matches(filename);
                for (int i = 0; i < mc2.Count; i++)
                {
                    if (i == 0)
                    {
                        ii.BeginTime = DateTime.Parse(mc2[i].Groups[0].Value+"-01");
                        ii.EndTime = DateTime.Parse(mc2[i].Groups[0].Value+"-01");
                    }
                    bFound = true;
                }
            }

            return ii;
        }
        private ImportInfo[] getImportInfosFromXPTable(bool succesed)
        {
            List<ImportInfo> importInfos = new List<ImportInfo>();
            foreach (Row row in fileTable.TableModel.Rows)
            {
                ImportInfo ii = new ImportInfo();
                ii.FullName = row.Cells[0].Text;
                ii.FileType = row.Cells[1].Text;
                ii.TimeType = row.Cells[2].Text;
                ii.BeginTime = System.Convert.ToDateTime(row.Cells[3].Data);
                ii.EndTime = System.Convert.ToDateTime(row.Cells[4].Data);
                ii.IsImport = row.Cells[5].Checked;
                ii.ErrorInfo = row.Cells[6].Text;
                ii.AlreadyImported = (bool)row.Tag;
                if (ii.AlreadyImported == succesed)
                    importInfos.Add(ii);
            }
            return importInfos.ToArray();
        }
        private ImportInfo getImportInfoFromRow(Row row)
        {
            ImportInfo ii = new ImportInfo();
            ii.FullName = row.Cells[0].Text;
            ii.FileType = row.Cells[1].Text;
            ii.TimeType = row.Cells[2].Text;
            ii.BeginTime = System.Convert.ToDateTime(row.Cells[3].Data);
            ii.EndTime = System.Convert.ToDateTime(row.Cells[4].Data);
            ii.IsImport = row.Cells[5].Checked;
            return ii;
        }
        private string getTableName(string fileType)
        {
            foreach (keyword2model km in keyword2Models)
            {
                if (km.Type == fileType)
                    return km.Value;
            }
            return null;
        }
        
        private ImportInfo getImportInfo(Row row)
        {
            ImportInfo ii = new ImportInfo();
            ii.FullName = row.Cells[0].Text;
            ii.FileType = row.Cells[1].Text;
            ii.TimeType = row.Cells[2].Text;
            ii.BeginTime = System.Convert.ToDateTime(row.Cells[3].Data);
            ii.EndTime = System.Convert.ToDateTime(row.Cells[4].Data);
            ii.IsImport = row.Cells[5].Checked;
            ii.AlreadyImported = (bool)row.Tag;
            ii.ErrorInfo = row.Cells[6].Text;
            return ii;
        }
        private void ImportData(Row row)
        {
            ImportInfo ii = getImportInfo(row);
            string tableName = getTableName(ii.FileType);
            string errInfo = "";
            bool success = false;
            int fileid = 0;

            if (this.InvokeRequired)
            {
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    row.BackColor = System.Drawing.Color.Blue;
                    fileTable.EnsureVisible(row.Index, 0);
                });
            }

            if (ii.IsImport)
            {
                try
                {
                    //判断该文件是否曾经导入过
                    string fileName = System.IO.Path.GetFileName(ii.FullName);
                    if (dataHelper.IsFileExist(currentShopId, fileName))
                        throw new Exception("该文件已经导入过了");

                    file_import fi = new file_import();
                    fi.employeeid = UserSession.EmployeeId;
                    fi.shopid = currentShopId;
                    fi.filename = fileName;
                    fi.filetype = ii.FileType;
                    fi.datetype = ii.TimeType;
                    fi.dodatetime = DateTime.Now;
                    fi.startdate = ii.BeginTime;
                    fi.enddate = ii.EndTime;
                    fi.tablename = tableName;
                    fileid = System.Convert.ToInt32(dataHelper.AddFileInfo(fi));

                    //导入该文件
                    int dataCount = dataHelper.ImportData(tableName, ii.FullName, currentShopId, fileid, ii.BeginTime, ii.EndTime);
                    errInfo = string.Format("成功导入{0}条数据", dataCount);
                    success = true;

                    string msg = string.Format("导入数据:文件编号:{0}, 表名:{1}, 店铺id:{2}, 记录数:{3}, 日期1:{4}, 日期2:{5}, 文件名:{6}", fileid, tableName, currentShopId, dataCount, ii.BeginTime, ii.EndTime, ii.FullName);
                    dataHelper.WriteLog(0, 0, msg);
                }
                catch (Exception ex)
                {
                    errInfo = ex.Message;

                    string msg = string.Format("导入数据:{0}, 表名:{1}, 店铺id:{2}, 出错:{3}", ii.FullName, tableName, currentShopId, errInfo);
                    dataHelper.WriteLog(0, 0, msg);

                    //出错时，要回滚?
                    dataHelper.CleanData(fileid, tableName);
                }
            }
            else
            {
                errInfo = "已跳过";
            }

            if (this.InvokeRequired)
            {
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    row.Tag = (object)success;
                    row.Cells[6].Text = errInfo;
                    row.BackColor = System.Drawing.Color.White;
                    if (!success)
                        row.ForeColor = System.Drawing.Color.Red;
                });
            }
        }

        private void importFunc()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    btnImport.Enabled = false;
                    lblInfo.Visible = true;
                    progressBar1.Visible = true;
                    progressBar1.Value = 0;
                    lblInfo.Text = "开始导入...";
                    progressBar1.Value = 0;
                    cbAll.Enabled = false;
                    btnRemoveSuccess.Enabled = false;
                });
            }

            int rowCount = fileTable.TableModel.Rows.Count;
            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
            {
                Row currentRow = fileTable.TableModel.Rows[rowIndex];

                if (this.InvokeRequired)
                {
                    this.BeginInvoke((MethodInvoker)delegate()
                    {
                        lblInfo.Text = "正在导入" + (rowIndex + 1) + "/" + rowCount + ": " + currentRow.Cells[0].Text;
                        progressBar1.Value = (rowIndex * 100 / rowCount) % 100;
                    });
                }

                ImportData(currentRow);

            }


            if (this.InvokeRequired)
            {
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    lblInfo.Text = "正在清除格式可能有误的无效记录,稍候...";
                    //清除可能格式错误的垃圾内容;
                    dataHelper.CleanRubbishData();

                    btnImport.Enabled = true;
                    lblInfo.Text = "导入完成";
                    progressBar1.Value = 100;
                    cbAll.Enabled = true;
                    btnRemoveSuccess.Enabled = true;
                });
            }
        }

        private void btnAddShop_Click(object sender, EventArgs e)
        {
            FormInput form = new FormInput("请输入店铺名称");
            if (form.ShowDialog() == DialogResult.OK)
            {
                if (form.Value != "")
                {
                    shop temp = dataHelper.GetShop(form.Value);
                    if ( temp != null)
                    {
                        MessageBox.Show("已经存在同名的店铺，请重新输入！", "添加店铺失败", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    }
                    else
                    {
                        dataHelper.WriteLog(0, 0, "添加店铺:" + form.Value);
                        dataHelper.AddShop(form.Value, null);
                        LoadShops();

                        MessageBox.Show("店铺添加成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
        }
        private void DataManageForm_Load(object sender, EventArgs e)
        {
            LoadShops();
            initKeyWordMap();
            InitFileTable();
            cbFileType.Items.Add("--所有--");
            cbFileType.Items.AddRange(getFileTypes());
            cbFileType.SelectedIndex = 0;
        }
        private void btnBrowse_Click(object sender, EventArgs e)
        {
            //读取上次路径;
            if (MySelectedPath == "")
            {
                MySelectedPath = ConfigurationManager.AppSettings["LastImportPath"];
            }

            FolderBrowserDialog path = new FolderBrowserDialog();
            if (Directory.Exists(MySelectedPath))
                path.SelectedPath = MySelectedPath;
            else
                path.SelectedPath = Application.StartupPath;
            if(path.ShowDialog() == DialogResult.OK)
            {
                //保存路径;
                MySelectedPath = path.SelectedPath;
                Configuration cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                cfg.AppSettings.Settings["LastImportPath"].Value = path.SelectedPath;
                cfg.Save(ConfigurationSaveMode.Modified);
                //强制重新载入配置文件
                ConfigurationManager.RefreshSection("AppSettings");  

                string baseDir = path.SelectedPath;
                txtFilePath.Text = baseDir.Trim();

                ArrayList fileInfos = new ArrayList();
                GetAllDirList(baseDir, fileInfos);

                this.fileTable.TableModel.Rows.Clear();
                int needNoticeCount = 0;
                foreach (FileInfo fi in fileInfos)
                {
                    ImportInfo ii = getImportFileInfo(fi);
                    Row row = new Row(new Cell[] {new Cell(ii.FullName),
								new Cell(ii.FileType),
                                new Cell(ii.TimeType),
								new Cell(ii.BeginTime),
                                new Cell(ii.EndTime),
								new Cell(null, ii.IsImport),
                                new Cell(ii.ErrorInfo)});
                    row.Tag = (bool)false;
                    if (!ii.IsImport)
                    {
                        needNoticeCount++;
                        row.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFECEC");
                        row.ForeColor = System.Drawing.ColorTranslator.FromHtml("#FF0000");
                    }
                    this.fileTable.TableModel.Rows.Add(row);
                }
            }
        }
        private void btnImport_Click(object sender, EventArgs e)
        {
            currentShopId = (int)((shop)cbShops.SelectedItem).shopid;

            if (thread != null)
            {
                if (thread.IsAlive)
                    thread.Abort();
            }
            thread = new Thread(importFunc);
            thread.Start();
        }
        private void cbAll_CheckedChanged(object sender, EventArgs e)
        {
            foreach (Row row in fileTable.TableModel.Rows)
            {
                row.Cells[5].Checked = cbAll.Checked;
            }
        }
        private void btnRemoveSuccess_Click(object sender, EventArgs e)
        {
            ImportInfo[] failImportInfos = getImportInfosFromXPTable(false);
            fileTable.TableModel.Rows.Clear();
            foreach (ImportInfo ii in failImportInfos)
            {
                Row row = new Row(new Cell[] {new Cell(ii.FullName),
								new Cell(ii.FileType),
                                new Cell(ii.TimeType),
								new Cell(ii.BeginTime),
                                new Cell(ii.EndTime),
								new Cell(null, ii.IsImport),
                                new Cell(ii.ErrorInfo)});
                row.Tag = (bool)false;
                this.fileTable.TableModel.Rows.Add(row);
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            int shopid = (int)((shop)cbShopList.SelectedItem).shopid;

            Dictionary<string, string> attrMap = dataHelper.GetTableFieldMap("file_import");
            DataTable table = dataHelper.GetFileImports(shopid, cbFileType.Text);
            foreach (KeyValuePair<string, string> item in attrMap)
            {
                table.Columns[item.Key].ColumnName = item.Value;
            }
            FileImportReport.DataSource = table;
        }

        private void btnDelFile_Click(object sender, EventArgs e)
        {
            if (FileImportReport.SelectedRows.Count > 0)
            {
                if (MessageBox.Show("确实要删除选定的已导入的文件吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    for (int i = 0; i < FileImportReport.RowCount; i++)
                    {
                        if (FileImportReport.Rows[i].Selected)
                        {
                            int fileid = System.Convert.ToInt32(FileImportReport.Rows[i].Cells[0].Value.ToString());
                            string tablename = FileImportReport.Rows[i].Cells[9].Value.ToString();
                            dataHelper.CleanData(fileid, tablename);

                            string msg = string.Format("删除数据: 文件编号{0}, 表名:{1}", fileid, tablename);
                            dataHelper.WriteLog(0, 0, msg);
                        }
                    }
                    btnRefresh_Click(sender, e);
                }
            }
            else
            {
                MessageBox.Show("请选择要删除的文件！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private void tabPage4_Enter(object sender, EventArgs e)
        {
            //dbtnRefresh_Click(sender, e);
        }

        private void cbShopList_SelectionChangeCommitted(object sender, EventArgs e)
        {
            btnRefresh_Click(sender, e);
        }

        private void cbFileType_SelectionChangeCommitted(object sender, EventArgs e)
        {
            btnRefresh_Click(sender, e);
        }
    }

    public class keyword2model
    {
        public string Type { get; set; }
        public string Keyword { get; set; }
        public string TimeType { get; set; }
        public string Value { get; set; }
    }

    public class ImportInfo
    {
        public string FullName { get; set; }
        public string FileType { get; set; }
        public string TimeType { get; set; }
        public DateTime BeginTime { get; set; }
        public DateTime EndTime { get; set; }
        public bool IsImport { get; set; }
        public bool AlreadyImported { get; set; }   //是否成功导入过一次
        public string ErrorInfo { get; set; }        //错误提示
    }
}
